package org.example.fboot.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.example.fboot.config.jwt.AccessComponent;
import org.example.fboot.dto.User;
import org.example.fboot.handler.BusException;
import org.example.fboot.mapper.UserMapper;
import org.example.fboot.result.RequestStat;
import org.example.fboot.result.Result;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import reactor.core.publisher.Mono;

import java.util.concurrent.Callable;
import java.util.function.Function;

@Slf4j
@Service
public class AuthServiceImpl implements AuthService {
    @Resource
    private ReactiveAuthenticationManager reactiveAuthenticationManager;
    @Resource
    private UserMapper userMapper;
    @Resource
    private PasswordEncoder passwordEncoder;

    @Override
    public Mono<Result<String>> login(Function<Authentication, String> fun, @Validated User user) {
        return reactiveAuthenticationManager.authenticate(
                        new UsernamePasswordAuthenticationToken(
                                user.getUsername(), user.getPassword()
                        )
                )
                .flatMap(result -> Mono.just(
                                Result.result(RequestStat.login, fun.apply(result))
                        )
                );
    }

    @Override
    public Mono<Result<String>> registerUser(Function<Authentication, String> fun, @Validated User user) {
        User one = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, user.getUsername()));
        if (one!=null){
            throw new BusException("用户名已存在");
        }
        User insertUser = new User();
        insertUser.setUsername(user.getUsername());
        insertUser.setPassword(passwordEncoder.encode(user.getPassword()));
        userMapper.insert(insertUser);
        return login(fun,user);
    }


}
